import requests
from bs4 import BeautifulSoup as bs
import os
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
import threading

urls = [
    'https://wiki.biligame.com/blhx/%E5%BD%B1%E7%94%BB%E7%9B%B8%E5%85%B3',
    'https://wiki.biligame.com/blhx/%E7%94%BB%E5%B8%88%E8%B4%BA%E5%9B%BE%E3%80%81%E5%90%8C%E4%BA%BA%E5%9B%BE%E5'
    '%90%88%E9%9B%86'
]
baseContent = []
header = {
    'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/84.0.4147.125 Safari/537.36 '
}


def initBase():
    for url in urls:
        response = requests.get(url, headers=header)
        response.encoding = 'utf-8'
        baseContent.append(response)
    print('爬取主页面完成')


class Spider(threading.Thread):
    def __init__(self, radioType, checkBoxType, savePath,isFast, show, header):
        threading.Thread.__init__(self)
        if header is None:
            self.header = {
                'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                              'Chrome/84.0.4147.125 Safari/537.36 '
            }
        else:
            self.header = header
        if savePath is None:
            self.savePath = "F:/pycharm项目/爬虫/结果/碧蓝图/"
        else:
            self.savePath = savePath
        self.radioType = eval(radioType)
        self.checkBoxType = checkBoxType
        self.show = show
        self.stop = False
        self.isFast=eval(isFast)
        print(isFast)
        if self.radioType == 0:
            self.all = baseContent[0]
        else:
            self.all = baseContent[1]

    def setMsg(self, newVal):
        self.show.setMsg(newVal)

    def setNowNum(self, newVal):
        self.show.setNowNum(newVal)

    def loadPage(self, url):
        response = requests.get(url, headers=self.header)
        response.encoding = 'utf-8'
        return response

    def write_page(self, content, filename):
        f = self.savePath + filename
        with open(f, 'ab') as file:
            file.write(content.content)
            print(f + '   保存完毕')
            self.setMsg(f + '   保存完毕')
            file.close()

    def getAllFileName(self, file_dir):
        # 控制循环次数，因为只要读取一次文件目录列表
        i = 1
        for root, dirs, files in os.walk(file_dir):
            if i > 2:
                break
            i += 1
            return files

    def checkFileName(self, fileName, allFileName):
        if fileName in allFileName:
            print('文件名重复')
            self.setMsg('文件名重复')
            return False
        else:
            return True

    def run(self):
        realImgPages = []
        imgs = self.getAllFileName(self.savePath)
        # types=bs(basePage.text, 'lxml').select('#mc_collapse-2 .thumb div')
        if self.radioType == 0:
            smallImgs = bs(self.all.text, 'lxml').select('.panel-info')[self.checkBoxType].select('.thumb div a')
        else:
            smallImgs = bs(self.all.text, 'lxml').select('.mw-gallery-packed-hover')[self.checkBoxType].select(
                '.thumb div a')

        print('https://wiki.biligame.com' + str(smallImgs[0].get('href')))

        for i in smallImgs:
            realImgPages.append('https://wiki.biligame.com' + i.get('href'))

        self.show.allNum.set(len(realImgPages))
        print('开始爬取')
        self.setMsg('开始爬取')

        # 应付更新的情况
        if len(realImgPages) <= len(imgs):
            print('本次未爬取的图片之前已爬取过')
            self.setMsg('本次未爬取的图片之前已爬取过')
            return
        if self.isFast==1:
            index = len(imgs)
        else:index=0
        print(len(realImgPages), len(imgs))
        i=[]
        while index < len(realImgPages):
            if self.stop:
                self.setMsg('已暂停')
                print('线程结束')
                break
            realImgPage = self.loadPage(realImgPages[index])
            imgName = str(bs(realImgPage.text, 'lxml').find(id='firstHeading').string)
            imgName = imgName[3:len(imgName)]

            print(imgName)
            i.append(imgName)
            if self.checkFileName(imgName, imgs):
                realImgSrc = bs(realImgPage.text, 'lxml').find(class_='internal').get('href')
                self.write_page(self.loadPage(realImgSrc), imgName)
            index += 1
            self.setNowNum(index)
        for a in range(0,len(i)):
            for b in range(a+1,len(i)):
                if i[a]==i[b]:
                    print('——————————')
                    print(i[a])

        if len(realImgPages) == index:
            self.setMsg('爬取完毕')
            print('爬取完毕')


class Show:
    def __init__(self):
        self.main = tk.Tk()
        self.msg = tk.StringVar()
        self.msg.set('此处显示当前状态信息，目前尚未开始爬取')
        self.allNum = tk.StringVar()
        self.allNum.set(0)
        self.nowNum = tk.StringVar()
        self.nowNum.set(0)
        self.spiderThread = None
        self.beginX = 20
        self.position = {'x': self.beginX, 'y': 20}
        self.interval = {'x': 130, 'y': 40}
        self.checkbox = [
            ('剧情地图/关卡背景/CG', '登录界面/更新界面/过场图', '特殊背景', '早期碧蓝壁纸', '国际服日服登录及过场'),
            ('国服三周年贺图', '碧蓝航线开服1000天贺图', '港澳台服上线贺图', '日服二周年贺图', '国服二周年贺图', '节日贺图', '一周年贺图', '实装贺图', '生日贺图', '美服贺图',
             '日服贺图', '国服贺图', '角色设定', '画师摸鱼', '周边商品')
        ]
        self.checkboxIndex = 0
        self.font = ('黑体', 12)

    def myPack(self, dom, x=0, y=0):
        dom.place(x=self.position['x'] + x, y=self.position['y'] + y)

    def tab(self):
        self.position['x'] += self.interval['x']

    def br(self):
        self.position['y'] += self.interval['y']
        self.position['x'] = self.beginX

    def getData(self, radioType, checkBoxType, savePath,isFast, header=None):
        if self.spiderThread is not None:
            self.spiderThread.stop = True
            self.spiderThread = None
        self.spiderThread = Spider(radioType, checkBoxType, savePath + '/', isFast,self, header)
        # self.spiderThread = threading.Thread(target=spider.run)
        self.spiderThread.start()

    def pause(self):
        self.spiderThread.stop = True

    def setMsg(self, val):
        self.msg.set(val)

    def setNowNum(self, val):
        self.nowNum.set(val)

    def initView(self):
        def changeType(i):
            cmb['value'] = self.checkbox[i]
            cmb.current(0)

        self.main.geometry('500x500+200+100')
        self.main.title('碧蓝爬虫')
        cmb = ttk.Combobox(self.main, value=self.checkbox[self.checkboxIndex], width=28)
        cmb.current(1)

        radio = tk.StringVar()
        radio.set(0)
        isFast = tk.StringVar()
        isFast.set(1)
        url1 = tk.StringVar()
        url1.set(urls[0])
        url2 = tk.StringVar()
        url2.set(urls[1])
        savePath = tk.StringVar()

        self.myPack(tk.Label(self.main, text='爬取对象', font=self.font))
        self.tab()
        self.myPack(tk.Radiobutton(self.main, text='壁纸和插画', variable=radio, value=0, command=lambda: changeType(0)))
        self.tab()
        self.myPack(tk.Radiobutton(self.main, text='贺图设定图', variable=radio, value=1, command=lambda: changeType(1)))
        self.br()

        self.myPack(tk.Label(self.main, text='具体类型', font=self.font))
        self.tab()
        self.myPack(cmb)
        self.br()

        self.myPack(tk.Label(self.main, text='贺图设定图链接', font=self.font))
        self.tab()
        self.myPack(tk.Entry(self.main, textvariable=url1, width=46))
        self.br()

        self.myPack(tk.Label(self.main, text='壁纸和插画链接', font=self.font))
        self.tab()
        self.myPack(tk.Entry(self.main, textvariable=url2, width=46))
        self.br()

        self.myPack(tk.Label(self.main, text='保存路径', font=self.font))
        self.tab()
        self.myPack(tk.Entry(self.main, textvariable=savePath, width=35))
        self.tab()
        self.tab()
        self.myPack(tk.Button(self.main, text='  选择路径  ', command=lambda: savePath.set(filedialog.askdirectory())),
                    x=-10, y=-5)
        self.br()

        self.myPack(tk.Label(self.main, text='爬取模式', font=self.font))
        self.tab()
        self.myPack(tk.Radiobutton(self.main, text='快速模式', variable=isFast, value=1))
        self.tab()
        self.myPack(tk.Radiobutton(self.main, text='全盘模式', variable=isFast, value=0))
        self.br()

        self.tab()
        self.myPack(tk.Button(self.main, text='  开  始  ',
                              command=lambda: self.getData(radio.get(), cmb.current(), savePath.get(),isFast.get())))
        self.tab()
        self.myPack(tk.Button(self.main, text='  暂  停  ', command=lambda: self.pause()))
        self.br()

        self.myPack(tk.Label(self.main, text='—————————————————————————————————', font=self.font), x=-25)
        self.br()
        # 输出控制消息
        self.myPack(tk.Label(self.main, text='信息  ', font=self.font))
        self.br()
        self.myPack(tk.Label(self.main, text='已保存：'))
        self.myPack(tk.Label(self.main, textvariable=self.nowNum), x=50, y=0)
        self.tab()
        self.myPack(tk.Label(self.main, text='需保存：'))
        self.myPack(tk.Label(self.main, textvariable=self.allNum), x=50, y=0)

        self.br()
        self.myPack(tk.Label(self.main, textvariable=self.msg))

        tag = '1.选择爬取的目标，爬取目标为wiki中的两个图片板块\n' \
              '2.选择具体种类，即wiki中可以展开折叠的标题，\n' \
              '3.两个爬取目标的链接可以在下面两个输入框中获取，\n' \
              '点击下面的输入框后使用Ctrl+A全选后再使用Ctrl+C复制即可获取爬取目标链接\n' \
              '4.点击“保存路径”按钮，选择需要保存的路径\n' \
              '5.选择爬取模式，如果保存文件符合“注意事项”，则选择快速模式，反之选择全盘模式\n' \
              '全盘模式速度慢，但保存文件不受限制，快速模式则相反，速度快，但保存文件需要符合下午的“注意事项”\n' \
              '6.点击“开始”按钮即可开始爬取，点击“暂停”按钮即可暂停爬取\n' \
              '7.下方的提示信息会告知当前保存完毕的图片以及是否暂停等状态\n\n' \
              '注意事项：\n为防止部分内容无法爬取，请不要将不同爬取目标的保存路径放在同一文件夹\n' \
              '首次爬取请选用空文件夹，此后不要对该文件夹进行改动，\n' \
              '如果需要将图片提取出此文件，请复制'
        tagView = tk.Tk()
        tagView.geometry('500x250+700+200')
        tagView.title('使用提示')
        tk.Label(tagView, text=tag, width=60, anchor="w", justify='left').pack()
        tk.mainloop()
        tk.mainloop()


if __name__ == '__main__':
    show = Show()
    initBase()
    show.initView()

